<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */

namespace App\Controller;

use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Psr\Container\ContainerInterface;
use Hyperf\Contract\ConfigInterface;

abstract class AbstractController
{
    const ERROR_CODE_BUSY = -1;
    const ERROR_CODE_NOT_LOGIN = -2;
    const ERROR_CODE_AUTH = -3;
    const ERROR_CODE_NETWORK_ERROR = -4;
    const ERROR_CODE_SERVER_ERROR = -5;
    const ERROR_CODE_REQUEST_ERROR = -6;
    const ERROR_CODE_TIMEOUT = -7;

    #[Inject]
    protected ContainerInterface $container;
    #[Inject]
    protected RequestInterface $request;
    #[Inject]
    protected ResponseInterface $response;
    #[Inject]
    protected ConfigInterface $config;

    /**
     * format to json success
     * 参考微信,见url错误码说明  https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/red-packet-cover/getRedPacketCoverUrl.html
     * example: return  $this->jsonSuccess(["id"=>1,"name"=>"张三"]) ;
     *          return $this->jsonSuccess("操作成功")
     *          return $this->jsonSuccess();
     * @param array $data
     * @param string|null $message
     * @return \Psr\Http\Message\ResponseInterface
     * @author 苏翔
     * @date 2024-08-13 13:07
     */
    function jsonSuccess($data = [], ?string $message = 'success')
    {
        if (is_string($data)) { // can use as jsonSuccess('操作成功');
            $message = $data;
            $data = [];
        }
        $message = $message ?: 'success';

        $res = ["code" => 200, "message" => $message, "data" => $data];
        if ($log = $this->getDevlog()) {
            $res['dev_log'] = $log;
        }

        return $this->response->json($res, JSON_UNESCAPED_UNICODE);
    }

    /**
     * format to json error
     * 参考微信,见url错误码说明  https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/red-packet-cover/getRedPacketCoverUrl.html
     * example: return  jsonError("操作失误,请检查");
     *          return jsonError(-8,['user'=>'username','email'=>'q@qq.cn']);
     *          return $this->jsonError(self::ERROR_CODE_BUSY);
     * @param int $code
     * @param string|null $message
     * @return \Psr\Http\Message\ResponseInterface
     * @author 苏翔
     * @date 2024-08-13 12:59
     */
    function jsonError($code = -1, array $args = [])
    {
        // can use $args
        $fnSetMsgArgs = function ($tpl, $data) {
            $pattern = '/\{\$([a-zA-Z_][a-zA-Z_0-9]*)\}/';
            return preg_replace_callback($pattern, function ($match) use ($data) {
                $key = $match[1];
                return isset($data[$key]) ? $data[$key] : '';
            }, $tpl);
        };

        if (!is_numeric($code)) { // can use as jsonError('您操作某某错误');
            $message = $code;
            $code = -100000;
        } else {
            $message = $this->config->get('errcode.' . $code, 'error');
            if ($args) {
                $message = $fnSetMsgArgs($message, $args);
            }
        }
        $res = ["code" => $code, "message" => $message, "data" => []];
        if($log=$this->getDevlog()){
            $res['dev_log']=$log;
        }
        return $this->response->json($res, JSON_UNESCAPED_UNICODE)->withStatus(500);
    }

    function getDevlog()
    {
        $log = [];
        if ($this->request->getHeader('dev_log')) {
            $dev_log = dev_log();
            foreach ($dev_log as $item) {
                [$k, $v] = $item;
                if (!is_scalar($v)) {
                    $v = var_export($v, true);
                    $v = str_replace('array (', '[', $v);
                    $v = str_replace(')', ']', $v);
                    $v = str_replace('=>', '=> ', trim($v));
                    $v = str_replace('  ', ' ', $v);
                    $v = str_replace("\n", "", $v);
                }
                $log[] = $k . ':' . $v;
            }
        }
        return $log;
    }
}